#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <MqttClient.h>
#include <ArduinoJson.h>
#define LED D6
char ssid[]         = "xxx";         // wifi名
char pass[]         = "xxx";//wifi密码
//char ssid[]         = "xxx";         // wifi名
//char pass[]         = "xxx";//wifi密码
const char broker[] = "xx.xx.xx";    //MQTT服务器地址
//const char broker[] = "xxx.xxx.xxx.xxx";
uint16_t        port     = 1883;             //端口
//String topic = "yf596O2LT11"; //订阅主题
//String p_topic = "yf596O2LT10"; //发送主题
String device_ID = "2147483644";
String applianceId,control,topic,p_topic;
String url = "http://xx.xx.xx/register.php?device_ID=";
uint16_t ront_time,control_time,current_time,delayed;
WiFiClient wifiClient;                 //初始化wifi库
MqttClient mqttClient(wifiClient);     //初始化MQTT库
HTTPClient http;
void setup() {
  Serial.begin(115200);               //设置串口波特率
  pinMode(LED, OUTPUT); //设置IO口为输出
  digitalWrite(LED, LOW);
  Serial.print("wif名: ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  while ( WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("网络连接成功");
  Serial.println();
  get_data();
  //get_data();
  // 您可以提供唯一的客户端ID, 如果未设置，则库使用Arduino-millis（）
  mqttClient.setId("device_ID"); // 每个客户端必须有一个唯一的客户端ID
  // mqttClient.setUsernamePassword("username", "password");// 您可以为身份验证提供用户名和密码
  Serial.print("MQTT网络地址: ");
  Serial.println(broker);
  if (!mqttClient.connect(broker, port)) {
    Serial.print("连接错误： ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("已连接到mqtt");
  mqttClient.onMessage(onMqttMessage);// 设置消息接收回调
  Serial.print("订阅的主题: ");
  Serial.println(topic);
  mqttClient.subscribe(topic);// 订阅主题
  // mqttClient.unsubscribe(topic);// 可以使用取消订阅主题:
  //Serial.print("Waiting for messages on topic: ");
  //Serial.println(topic);
  
}
void loop() {
  mqttClient.poll(); //轮询mqtt
  ledoo();
  dings();
}

void dings(){
  uint16_t t =millis();
  uint16_t i = t-ront_time;
  if(i > 15000){
    String az = "{\"applianceId\": ";
    az += device_ID;
    az += ",\"state\": 1}";
    postMessage(az);
    ront_time = millis();
  }
}
void ledoo(){
  //Serial.println(applianceId == device_ID));
  if(applianceId == device_ID){
    //判断控制信号有无延时
    current_time = millis();
    Serial.println("当前时间：");
    Serial.println(current_time);
    Serial.print("延时时间：");
    Serial.print(delayed);
    Serial.print("秒");
    applianceId = "";
    control_time = current_time+delayed*1000;
    //等待时间到后进行控制操作
    if(control_time < millis() && control_time > 0){
      if(control == "off"){//控制信号为关
        digitalWrite(LED, LOW);
        Serial.println("关闭灯");
        control_time = -1;
        applianceId = ""; 
        String az = "{\"applianceId\": ";
        az += device_ID;
        az += ",\"control\": \"off\",\"delayed\": 0}";
        postMessage(az);
      }
      //控制信号为开
      if(control == "on"){
        digitalWrite(LED, HIGH);
        Serial.println("打开灯");
        control_time = -1;
        applianceId = ""; 
        String az = "{\"applianceId\": ";
        az += device_ID;
        az += ",\"control\": \"on\",\"delayed\": 0}";
        postMessage(az);     
      }
    } 
  }
}
void onMqttMessage(int messageSize) {
  String news,t;
  // we received a message, print out the topic and contents
  //Serial.print("订阅的主题：");
  //Serial.println(mqttClient.messageTopic());
  Serial.print("接收到的数据：");
  Serial.print(messageSize);
  Serial.println(" bytes:");
  // 获取订阅主题下发的消息
  while (mqttClient.available()) {
     news += (char)mqttClient.read();   
  }
  char nxew[200];
  strcpy(nxew,news.c_str());
  StaticJsonDocument<200> doc;
  DeserializationError error = deserializeJson(doc, nxew);
  /*if (error) {
    Serial.print(F("解析失败： "));
    Serial.println(error.c_str());
    return;
  }*/
  
  String app = doc["applianceId"];
  applianceId = app;
  String control_1 = doc["control"];
  control = control_1;
  delayed = doc["delayed"];
  Serial.print("设备ID：");
  Serial.println(applianceId);
  Serial.print("控制消息：");
  Serial.println(control);
  Serial.print("延时：");
  Serial.print(delayed);
  Serial.println("秒");
}

void postMessage(String state){
    Serial.print("订阅的主题: ");
    Serial.println(p_topic);
    Serial.print("返回的消息: ");
    Serial.println(state);
    mqttClient.beginMessage(p_topic);
    mqttClient.print(state);
    mqttClient.endMessage();
    Serial.println();
}

String get_data()
{
  url += device_ID;
  Serial.print("[HTTP] begin...\n");
  http.begin(wifiClient,url);
  Serial.print("[HTTP] GET...\n");
  int httpCode = http.GET();
  if (httpCode > 0) {
    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      topic = payload + "1";
      p_topic = payload + "0";
      Serial.println(payload);
      }
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }
        http.end();
        //delay(10000);
        }
